import * as THREE from 'three';

/**
 * 创建连接线工具函数
 * @param {THREE.Group} models - 需要添加连接线的3D场景组
 * @param {Object} [options={}] - 配置选项
 * @returns {Object} 包含线容器、更新方法和销毁方法的对象
 */
export default function createConnectingLines(models, options = {}) {
    // 默认配置（使用Object.freeze防止被修改）
    const DEFAULTS = Object.freeze({
        lineColor: 0xff0000,        // 线条颜色（红色）
        opacity: 0.5,               // 透明度
        lineWidth: 1,               // 线宽
        dashed: false,              // 是否虚线
        dashPattern: [1, 1],        // 虚线模式（实线长度，间隔长度）
        maxLines: 1000              // 最大线条数量限制
    });

    // 合并配置（使用Object.seal防止添加新属性）
    const config = Object.seal({ ...DEFAULTS, ...options });

    // 创建线容器（禁用自动矩阵更新以提高性能）
    const lineContainer = new THREE.Group();
    lineContainer.matrixAutoUpdate = false;  // 手动控制矩阵更新
    models.add(lineContainer);

    // 线条对象池和活跃线条计数器
    const linePool = [];      // 线条对象池
    let activeLineCount = 0;   // 当前活跃线条数量

    // 材质缓存（避免重复创建）
    let cachedMaterial = null;
    
    /**
     * 创建线条材质
     * @returns {THREE.Material} 线条材质对象
     */
    const createLineMaterial = () => {
        if (cachedMaterial) return cachedMaterial;  // 返回缓存材质

        // 基础材质参数
        const baseParams = {
            color: new THREE.Color(config.lineColor),
            transparent: config.opacity < 1,  // 只有透明度<1时才启用透明
            opacity: config.opacity,
            depthWrite: false,  // 禁用深度写入（提高透明物体渲染性能）
            linewidth: config.lineWidth
        };

        // 根据配置选择创建实线或虚线材质
        cachedMaterial = config.dashed 
            ? new THREE.LineDashedMaterial({
                ...baseParams,
                dashSize: config.dashPattern[0],  // 虚线片段长度
                gapSize: config.dashPattern[1]    // 虚线间隔长度
            })
            : new THREE.LineBasicMaterial(baseParams);

        return cachedMaterial;
    };

    const lineMaterial = createLineMaterial();

    /**
     * 从对象池获取或创建新线条
     * @returns {THREE.Line|null} 返回线条对象或null（达到最大限制时）
     */
    const getLineFromPool = () => {
        // 检查是否达到最大线条限制
        if (activeLineCount >= config.maxLines) {
            console.warn(`已达到最大线条数量限制: ${config.maxLines}`);
            return null;
        }

        // 如果对象池中有可用线条，则复用
        if (linePool.length > activeLineCount) {
            return linePool[activeLineCount++];
        }

        // 创建新线条几何体
        const geometry = new THREE.BufferGeometry();
        geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(0), 3));
        
        // 创建线条对象
        const line = new THREE.Line(geometry, lineMaterial);
        line.frustumCulled = false;  // 禁用视锥体剔除（始终渲染）
        
        // 添加到对象池和容器中
        linePool.push(line);
        lineContainer.add(line);
        activeLineCount++;
        
        return line;
    };

    /**
     * 更新连接线
     * @param {Array} [connections=[]] - 连接点数据数组
     */
    const updateLines = (connections = []) => {
        activeLineCount = 0;  // 重置活跃线条计数器
        
        // 快速返回空连接情况
        if (!connections.length) return;

        // 分批处理连接数据（提高性能）
        const batchSize = 100;  // 每批处理100条连接
        for (let i = 0; i < connections.length; i += batchSize) {
            const batch = connections.slice(i, i + batchSize);
            
            batch.forEach(connection => {
                const line = getLineFromPool();
                if (!line) return;  // 达到最大限制时跳过

                const positionCount = connection.length;
                const geometry = line.geometry;
                
                // 获取或创建位置属性
                let positionAttribute = geometry.getAttribute('position');
                const neededSize = positionCount * 3;  // 每个点需要3个浮点数(x,y,z)
                
                // 如果属性不存在或大小不够，则创建新属性
                if (!positionAttribute || positionAttribute.array.length < neededSize) {
                    positionAttribute = new THREE.BufferAttribute(new Float32Array(neededSize), 3);
                    geometry.setAttribute('position', positionAttribute);
                } else if (positionAttribute.count !== positionCount) {
                    positionAttribute.count = positionCount;  // 更新顶点数量
                }

                // 更新位置数据
                const positionArray = positionAttribute.array;
                for (let j = 0; j < positionCount; j++) {
                    const point = connection[j];
                    if (!point) continue;  // 跳过无效点
                    
                    const offset = j * 3;
                    positionArray[offset] = point.x;
                    positionArray[offset + 1] = point.y;
                    positionArray[offset + 2] = point.z;
                }

                positionAttribute.needsUpdate = true;  // 标记需要更新
                geometry.setDrawRange(0, positionCount);  // 设置渲染范围

                // 虚线需要计算线距离
                if (config.dashed) {
                    line.computeLineDistances();
                }
            });
        }

        // 隐藏未使用的线条（通过设置渲染范围为0）
        for (let i = activeLineCount; i < linePool.length; i++) {
            linePool[i].geometry.setDrawRange(0, 0);
        }

        lineContainer.updateMatrix();  // 手动更新容器矩阵
    };

    const updateLine = (connection) => {
        
    }

    // 返回API接口（使用Object.freeze防止修改）
    return Object.freeze({
        get lineContainer() { return lineContainer; },  // 只读访问线容器
        updateLines,  // 更新线条方法
        dispose: () => {   // 销毁方法
            models.remove(lineContainer);
            linePool.forEach(line => {
                line.geometry.dispose();  // 释放几何体内存
            });
            if (cachedMaterial) {
                cachedMaterial.dispose();  // 释放材质内存
                cachedMaterial = null;
            }
        }
    });
}